package slice

import (
	"fmt"
	"ibdreader/mysql_def"
)

type Input struct {
	Data     []byte
	Position int64
}

var IN Input

func Position() int64 {
	return IN.Position
}

func SetPosition(pos int64) {
	IN.Position = pos
}

func IncPosition(delta int64) Input {
	if IN.Position+delta > mysql_def.UNIV_PAGE_SIZE {
		fmt.Println("please check position!")
	}
	IN.Position += delta
	return IN
}

func DecrPosition(delta int64) Input {
	if IN.Position-delta < 0 {
		fmt.Println("please check position!")
	}
	IN.Position -= delta
	return IN
}

func Available() int64 {
	return int64(len(IN.Data)) - IN.Position
}

func ReadBoolean() bool {
	return ReadByte() != 0
}

func Read() int64 {
	return int64(ReadByte())
}

func ReadByte() byte {
	v := decodeByte(IN)
	IN.Position++
	return v
}

func ReadUnsignedByte() int64 {
	return int64(ReadByte() & 0xff)
}

func ReadShortInt16() int64 {
	v := decodeInt16(IN)
	IN.Position += 2
	return v
}

func ReadUnsignedShort() int64 {
	return ReadShortInt16() & 0xffff
}

func read3BytesInt() int64 {
	v := decode3BytesInt(IN)
	IN.Position += 3
	return v
}

func ReadUnsigned3BytesInt() int64 {
	return read3BytesInt() & 0xffffff
}

func ReadInt() int64 {
	v := decodeInt32(IN)
	IN.Position += 4
	return v
}

func ReadUnsignedInt() int64 {
	return ReadInt() & 0xffffffff
}

func read6BytesInt() int64 {
	v := decode6BytesInt(IN)
	IN.Position += 6
	return v
}

func ReadUnsigned6BytesInt() int64 {
	return read6BytesInt() & 0xffffffffffff
}

func ReadLongInt64() int64 {
	v := decodeInt64(IN)
	IN.Position += 8
	return v
}

func IfUndefined(val int64) int64 {
	if val == 4294967295 {
		return -1
	}
	return val
}

func SkipBytes(length int64) int64 {
	len := Min(length, Available())
	IN.Position += len
	return len
}

func ReadByteArray(len int64) []byte {
	// deep copy is preferred here
	value := IN.getBytes(IN.Position, len)
	IN.Position += len
	return value
}

func (inp Input) getBytes(pos int64, len int64) []byte {
	value := make([]byte, len)
	//getBytes(index, value, 0, len)
	inp.Position = pos
	value = inp.Data[pos : pos+len]
	return value
}

func Min(x, y int64) int64 {
	if x < y {
		return x
	}
	return y
}
